home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr49 / chk_sd.zip / CHECK_SD.C next >
C/C++ Source or Header  |  1993-07-21  |  76KB  |  1,847 lines

  1. /****************************************************************************\
  2. *
  3. *               Microsoft Developer Support
  4. *               Copyright (c) 1992, 1993 Microsoft Corporation
  5. *
  6. * MODULE:       check_sd.c
  7. *
  8. *               In the Win32 .hlp file, if you click on Search, goto "Security
  9. *                 Overview", then choose from the list of topics under
  10. *                 Security Overview the sub-topic "Allowing Access", you'll
  11. *                 find the comment
  12. *
  13. *                 Note:  It is fine to write code like this that builds
  14. *                   security descriptors from scratch.  It is, however, a good
  15. *                   practice for people who write code that builds or
  16. *                   manipulates security descriptors to first write code that
  17. *                   explores the default security descriptors that Windows NT
  18. *                   places on objects.  For example, if Windows NT by default
  19. *                   includes in a DACL an ACE granting the Local Logon SID
  20. *                   certain access, it's good to know that, so that a decision
  21. *                   not to grant any access to the Local Logon SID would be a
  22. *                   conscious decision
  23. *
  24. * PURPOSE:      The comment in the .hlp file is accurate, however, for many
  25. *                 people this task of examining the SD is easier if there is
  26. *                 sample code to start from.  So, the purpose of this sample
  27. *                 is to assist people by providing sample code people can
  28. *                 start from as they examine SD(s).  This sample as is
  29. *                 examines the SD on files, and this code can be modified to
  30. *                 examine the SD on other objects
  31. *
  32. *               This sample is not a supported utility
  33. *
  34. * TO RUN:       Type Check_sd to check the SD on the \\.\A:  device
  35. *
  36. *               Type Check_sd d:\a.fil to check the SD on the d:\a.fil file.
  37. *                 In this case d:  must be formatted NTFS, because only NTFS
  38. *                 files have SD(s)
  39. *
  40. \****************************************************************************/
  41.  
  42. /****************************************************************************\
  43. *  INCLUDES, DEFINES
  44. \****************************************************************************/
  45. #define STRICT
  46. #include <windows.h>
  47. #include <stdlib.h>
  48. #include <stdio.h>
  49.  
  50. #define PERR(api) printf("\n%s: Error %d from %s on line %d",  \
  51.     __FILE__, GetLastError(), api, __LINE__);
  52. #define PMSG(msg) printf("\n%s line %d: %s",  \
  53.     __FILE__, __LINE__, msg);
  54.  
  55. /****************************************************************************\
  56. * GLOBAL VARIABLES AND TYPEDEFS
  57. \****************************************************************************/
  58.  
  59. typedef enum _KINDS_OF_ACCESSMASKS_DECODED {
  60.     FileAccessMask,
  61.     ProcessAccessMask,
  62.     WindowStationAccessMask,
  63.     RegKeyAccessMask,
  64.     ServiceAccessMask,
  65.     DefaultDaclInAccesTokenAccessMask
  66.     } KINDS_OF_ACCESSMASKS_DECODED, * PKINDS_OF_ACCESSMASKS_DECODED;
  67.  
  68. // These hold the well-known SIDs
  69.  
  70. PSID psidNullSid;
  71. PSID psidWorldSid;
  72. PSID psidLocalSid;
  73. PSID psidCreatorOwnerSid;
  74. PSID psidCreatorGroupSid;
  75. PSID psidNtAuthoritySid;
  76. PSID psidDialupSid;
  77. PSID psidNetworkSid;
  78. PSID psidBatchSid;
  79. PSID psidInteractiveSid;
  80. PSID psidLogonIdsSid; // But the X and Y values are bogus at first!!! (See below)
  81. PSID psidServiceSid;
  82. PSID psidLocalSystemSid;
  83. PSID psidBuiltinDomainSid;
  84.  
  85. /****************************************************************************\
  86. * FUNCTION PROTOTYPES
  87. \****************************************************************************/
  88.  
  89. VOID ExamineAccessToken(HANDLE hAccessToken);
  90. BOOL ExamineSD    (PSECURITY_DESCRIPTOR psdSD,
  91.                    KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask);
  92. BOOL ExamineACL   (PACL paclACL,              LPTSTR lpszOldIndent,
  93.                    KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask);
  94. VOID ExamineMask  (ACCESS_MASK amMask,        LPTSTR lpszOldIndent,
  95.                    KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask);
  96. BOOL LookupSIDName(PSID psidSID,              LPTSTR lpszOldIndent);
  97. BOOL SIDStringName(PSID psidSID, LPTSTR lpszSIDStringName);
  98. BOOL SetPrivilegeInAccessToken(VOID);
  99. VOID InitializeWellKnownSIDs(VOID);
  100. VOID DisplayHelp(VOID);
  101.  
  102. UINT main(UINT argc, char *argv[])
  103. {
  104.  
  105.   HANDLE               hProcess;
  106.   HANDLE               hAccessToken;
  107.   #define         DEFAULT_FILE_TO_CHECK "\\\\.\\A:"
  108.   #define                   SZ_NAME_BUF MAX_PATH
  109.   UCHAR           ucPathBuf[SZ_NAME_BUF];
  110.   LPTSTR          lpszFullName = (LPTSTR)&ucPathBuf;
  111.   #define                           SZ_SD_BUF 8096
  112.   UCHAR                ucBuf       [SZ_SD_BUF] = "";
  113.   DWORD                dwSDLength = SZ_SD_BUF;
  114.   DWORD                dwSDLengthNeeded;
  115.   PSECURITY_DESCRIPTOR psdSD      = (PSECURITY_DESCRIPTOR)&ucBuf;
  116.   DWORD                dwErrorMode;
  117.  
  118.   /**************************************************************************\
  119.   *
  120.   * This sample is not inside a Win32 service, however if this code were to be
  121.   *   moved inside a Win32 service, the following defines and code that
  122.   *   redirects stdout will be handy, because services cannot write to the
  123.   *   screen
  124.   *
  125.   * You may wish to choose a different file name for the output file if you
  126.   *   use this mechanism - note that the "w+" will destroy an existing file!
  127.   *
  128.   \**************************************************************************/
  129.  
  130.   #define WE_ARE_IN_A_SERVICE_SO_REDIRECT_STDOUT (0==1)
  131.   #define   FILE_TO_REDIRECT_STDOUT_TO "c:\\check_sd.out"
  132.  
  133.   if     (WE_ARE_IN_A_SERVICE_SO_REDIRECT_STDOUT)
  134.   { freopen(FILE_TO_REDIRECT_STDOUT_TO,"w+",stdout);
  135.   }
  136.  
  137.  
  138.   if      (1 == argc)
  139.   { strcpy(lpszFullName,DEFAULT_FILE_TO_CHECK);
  140.   }
  141.   else if (2 == argc)
  142.   { strcpy(lpszFullName,argv[1]);
  143.   }
  144.   else
  145.   { DisplayHelp();
  146.     return(0);
  147.   }
  148.  
  149.   /**************************************************************************\
  150.   *
  151.   * Set up the well-known SID(s) in global variables, and enable the privilege
  152.   *   needed in the access token to work with SACL(s)
  153.   *
  154.   \**************************************************************************/
  155.  
  156.   InitializeWellKnownSIDs();
  157.  
  158.   if (!SetPrivilegeInAccessToken())
  159.   { return(1);
  160.   }
  161.  
  162.   /**************************************************************************\
  163.   *
  164.   * This sample's primary purpose is to explore Security Descriptors.
  165.   *   However, it is all too easy to over-focus on SD(s), while losing isght
  166.   *   of the importance of Access Tokens.  So, we will now digress briefly to
  167.   *   examine the access token of the current process
  168.   *
  169.   \**************************************************************************/
  170.  
  171.   hProcess = GetCurrentProcess();
  172.   if (!hProcess)
  173.   { PERR("GetCurrentProcess");
  174.     return(1);
  175.   }
  176.  
  177.   if (!OpenProcessToken(hProcess,
  178.                         (TOKEN_READ | TOKEN_QUERY_SOURCE),
  179.                         &hAccessToken))
  180.   { PERR("OpenProcessToken");
  181.     return(1);
  182.   }
  183.  
  184.   ExamineAccessToken(hAccessToken);
  185.  
  186.   /**************************************************************************\
  187.   *
  188.   * Back to examining SD(s)
  189.   *
  190.   \**************************************************************************/
  191.  
  192.   printf("\nChecking SD on %s",lpszFullName);
  193.  
  194.   /**************************************************************************\
  195.   *
  196.   * SetErrorMode so we don't get the error due to no floppy disk in the floppy
  197.   *   drive
  198.   *
  199.   \**************************************************************************/
  200.  
  201.   dwErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS);
  202.  
  203.   if (!GetFileSecurity
  204.         (lpszFullName,
  205.          (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
  206.                                | GROUP_SECURITY_INFORMATION
  207.                                | DACL_SECURITY_INFORMATION
  208.                                | SACL_SECURITY_INFORMATION),
  209.          psdSD,
  210.          dwSDLength,
  211.          (LPDWORD)&dwSDLengthNeeded))
  212.   { PERR("GetFileSecurity");
  213.     return(1);
  214.   }
  215.  
  216.   SetErrorMode(dwErrorMode);
  217.  
  218.   if(!ExamineSD(psdSD,FileAccessMask))
  219.   { PERR("ExamineSD failed");
  220.     return(1);
  221.   }
  222.  
  223.   /**************************************************************************\
  224.   *
  225.   * The above code showed how to examine an SD on a file.  There are SDs on
  226.   *   other objects that could be examined by the function ExamineSD (and the
  227.   *   other functions it calls).  The following are one example call each of
  228.   *   the other four api's that are used to retrieve the SD from each of the
  229.   *   types of Win32 objects that can have an SD
  230.   *
  231.   * These calls will execute properly without any work on your part, however,
  232.   *   some work on your part will be required to get the sample calls below to
  233.   *   show the SD for the objects your program uses!  You would need to make
  234.   *   copy of this sample in a new directory, and write the code to get a
  235.   *   handle to the object you're interested in, so you can pass that handle
  236.   *   to the applicable api call below
  237.   *
  238.   * To insert the SD checking code into your own code you would do
  239.   *   something like
  240.   *
  241.   * 1) Add the global variables above in your globals
  242.   *
  243.   * 2) Add the function prototypes above in your globals
  244.   *
  245.   * 3) Add the includes and PERR/PMSG macroes above to your code
  246.   *
  247.   * 4) Add all the functions defined below (except DisplayHelp and except
  248.   *   ExamineAccessToken) to your code
  249.   *
  250.   * 5) Add a call sequence such as that in main() above that gets an
  251.   *   SD and passes it to Examine SD.  Or add a call sequence such as
  252.   *   one of those that follows that gets a handle, gets the SD on the
  253.   *   object the handle addresses, then calls ExamineSD
  254.   *
  255.   * 6) If you are examining a type SD not already listed in
  256.   *   KINDS_OF_ACCESSMASKS_DECODED, then you will have to add the new type to
  257.   *   KINDS_OF_ACCESSMASKS_DECODED, and add to ExamineMask() the necessary
  258.   *   code to crack that type of SD's access mask bits into the defines
  259.   *
  260.   \**************************************************************************/
  261.  
  262.   #define I_DO_NOT_WANT_THIS_CODE_TO_CLUTTER_THIS_PROGRAM_S_OUTPUT (0==0)
  263.  
  264.   if    (!I_DO_NOT_WANT_THIS_CODE_TO_CLUTTER_THIS_PROGRAM_S_OUTPUT)
  265.   { HANDLE    hProcess;
  266.     HANDLE    hWindowStation;
  267.     HKEY      hKey;
  268.     SC_HANDLE schService;
  269.     SC_HANDLE schSCManager;
  270.     SECURITY_INFORMATION siSInfo =
  271.          (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
  272.                                | GROUP_SECURITY_INFORMATION
  273.                                | DACL_SECURITY_INFORMATION
  274.                                | SACL_SECURITY_INFORMATION);
  275.  
  276.     printf("\n\nChecking SD on current process");
  277.  
  278.     hProcess = GetCurrentProcess();
  279.     if (!hProcess)
  280.     { PERR("GetCurrentProcess");
  281.       return(1);
  282.     }
  283.  
  284.     dwSDLength = SZ_SD_BUF;
  285.  
  286.     if (!GetKernelObjectSecurity
  287.           (hProcess,
  288.            (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
  289.                                  | GROUP_SECURITY_INFORMATION
  290.                                  | DACL_SECURITY_INFORMATION),
  291.            psdSD,
  292.            dwSDLength,
  293.            (LPDWORD)&dwSDLengthNeeded))
  294.     { PERR("GetKernelObjectSecurity");
  295.       return(1);
  296.     }
  297.  
  298.     /************************************************************************\
  299.     *
  300.     * It is important to close all handles as soon as your code no longer
  301.     *   needs them.  This conserves system resources.  In a sample such as
  302.     *   this one, the practical effect is close to nil, since as soon as the
  303.     *   sample exits (which only takes a few seconds, Windows NT destroys the
  304.     *   process this sample was running in, which reclaims all resources
  305.     *
  306.     * However, in a program that creates many objects (such as threads), or
  307.     *   where that program will be running for a long time, closing handles as
  308.     *   soon as the program no longer needs them can save significant
  309.     *   resources
  310.     *
  311.     * It is a good coding practice to make a habit of closing handles as soon
  312.     *   as your code no longer needs the handle
  313.     *
  314.     \************************************************************************/
  315.  
  316.     CloseHandle(hProcess);
  317.  
  318.     if(!ExamineSD(psdSD,ProcessAccessMask))
  319.     { PERR("ExamineSD failed");
  320.       return(1);
  321.     }
  322.  
  323.  
  324.     printf("\n\nChecking SD on current Window-station");
  325.  
  326.     hWindowStation = GetProcessWindowStation();
  327.     if (INVALID_HANDLE_VALUE == hWindowStation)
  328.     { PERR("GetProcessWindowStation");
  329.       return(1);
  330.     }
  331.  
  332.     dwSDLength = SZ_SD_BUF;
  333.  
  334.     if (!GetUserObjectSecurity
  335.           (hWindowStation,
  336.            &siSInfo,
  337.            psdSD,
  338.            dwSDLength,
  339.            (LPDWORD)&dwSDLengthNeeded))
  340.     { PERR("GetUserObjectSecurity");
  341.       return(1);
  342.     }
  343.  
  344.     CloseHandle(hWindowStation);
  345.  
  346.     if(!ExamineSD(psdSD,WindowStationAccessMask))
  347.     { PERR("ExamineSD failed");
  348.       return(1);
  349.     }
  350.  
  351.  
  352.     printf("\n\nChecking SD on registry key HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet");
  353.  
  354.     if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  355.                                       "SYSTEM\\CurrentControlSet",
  356.                                       0,
  357.                                       KEY_READ,
  358.                                       &hKey))
  359.     { PERR("RegOpenKeyEx");
  360.       return(1);
  361.     }
  362.  
  363.     dwSDLength = SZ_SD_BUF;
  364.  
  365.     if (ERROR_SUCCESS != RegGetKeySecurity
  366.           (hKey,
  367.            (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
  368.                                  | GROUP_SECURITY_INFORMATION
  369.                                  | DACL_SECURITY_INFORMATION),
  370.            psdSD,
  371.            &dwSDLength))
  372.     { PERR("RegGetKeySecurity");
  373.       return(1);
  374.     }
  375.  
  376.     RegCloseKey(hKey);
  377.  
  378.     if(!ExamineSD(psdSD,RegKeyAccessMask))
  379.     { PERR("ExamineSD failed");
  380.       return(1);
  381.     }
  382.  
  383.  
  384.     /************************************************************************\
  385.     *
  386.     * Any service will do here, just be sure to pick one that is in the
  387.     *   Service Control Manager's database, and use the service name, not the
  388.     *   service's display name.  For example, ClipSrv is displayed as Clipbook
  389.     *   in the Services Control Panel applet
  390.     *
  391.     \************************************************************************/
  392.  
  393.     printf("\n\nChecking SD on service Clipbook");
  394.  
  395.     schSCManager = OpenSCManager(
  396.                         NULL,                 // machine (NULL == local)
  397.                         NULL,                 // database (NULL == default)
  398.                         SC_MANAGER_ALL_ACCESS // access required
  399.                         );
  400.  
  401.     if (!schSCManager)
  402.     { PERR("OpenSCManager");
  403.       return(1);
  404.     }
  405.  
  406.     schService = OpenService(schSCManager,"ClipSrv",SERVICE_ALL_ACCESS);
  407.     if (!schService)
  408.     { PERR("OpenService");
  409.       return(1);
  410.     }
  411.  
  412.     CloseServiceHandle(schSCManager);
  413.  
  414.     dwSDLength = SZ_SD_BUF;
  415.  
  416.     if (!QueryServiceObjectSecurity
  417.           (schService,
  418.            (SECURITY_INFORMATION)( OWNER_SECURITY_INFORMATION
  419.                                  | GROUP_SECURITY_INFORMATION
  420.                                  | DACL_SECURITY_INFORMATION),
  421.            psdSD,
  422.            dwSDLength,
  423.            (LPDWORD)&dwSDLengthNeeded))
  424.     { PERR("QueryServiceObjectSecurity");
  425.       return(1);
  426.     }
  427.  
  428.     CloseServiceHandle(schService);
  429.  
  430.     if(!ExamineSD(psdSD,ServiceAccessMask))
  431.     { PERR("ExamineSD failed");
  432.       return(1);
  433.     }
  434.   }
  435.  
  436.   return(0);
  437. }
  438.  
  439. /****************************************************************************\
  440. *
  441. * FUNCTION: ExamineSD
  442. *
  443. \****************************************************************************/
  444.  
  445. BOOL ExamineSD    (PSECURITY_DESCRIPTOR psdSD,
  446.                    KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask)
  447. {
  448.  
  449.   PACL                        paclDACL;
  450.   PACL                        paclSACL;
  451.   BOOL                        bHasDACL        = FALSE;
  452.   BOOL                        bHasSACL        = FALSE;
  453.   BOOL                        bDaclDefaulted  = FALSE;
  454.   BOOL                        bSaclDefaulted  = FALSE;
  455.   BOOL                        bOwnerDefaulted = FALSE;
  456.   BOOL                        bGroupDefaulted = FALSE;
  457.   PSID                        psidOwner;
  458.   PSID                        psidGroup;
  459.   SECURITY_DESCRIPTOR_CONTROL sdcSDControl;
  460.   DWORD                       dwSDRevision;
  461.  
  462.   if (!IsValidSecurityDescriptor(psdSD))
  463.   { PERR("IsValidSecurityDescriptor");
  464.     return(FALSE);
  465.   }
  466.  
  467.   printf("\nSD is valid");
  468.  
  469.   if (!GetSecurityDescriptorDacl(psdSD,
  470.                                  (LPBOOL)&bHasDACL,
  471.                                  (PACL *)&paclDACL,
  472.                                  (LPBOOL)&bDaclDefaulted))
  473.   { PERR("GetSecurityDescriptorDacl");
  474.     return(FALSE);
  475.   }
  476.  
  477.   if (!GetSecurityDescriptorSacl(psdSD,
  478.                                  (LPBOOL)&bHasSACL,
  479.                                  (PACL *)&paclSACL,
  480.                                  (LPBOOL)&bSaclDefaulted))
  481.   { PERR("GetSecurityDescriptorSacl");
  482.     return(FALSE);
  483.   }
  484.  
  485.   if (!GetSecurityDescriptorOwner(psdSD,
  486.                                   (PSID *)&psidOwner,
  487.                                   (LPBOOL)&bOwnerDefaulted))
  488.   { PERR("GetSecurityDescriptorOwner");
  489.     return(FALSE);
  490.   }
  491.  
  492.   if (!GetSecurityDescriptorGroup(psdSD,
  493.                                   (PSID *)&psidGroup,
  494.                                   (LPBOOL)&bGroupDefaulted))
  495.   { PERR("GetSecurityDescriptorGroup");
  496.     return(FALSE);
  497.   }
  498.  
  499.   if (!GetSecurityDescriptorControl(psdSD,
  500.                                     (PSECURITY_DESCRIPTOR_CONTROL)&sdcSDControl,
  501.                                     (LPDWORD)&dwSDRevision))
  502.   { PERR("GetSecurityDescriptorControl");
  503.     return(FALSE);
  504.   }
  505.  
  506.   if (SE_SELF_RELATIVE & sdcSDControl)
  507.     printf("\nSD is in self-relative format (all SDs returned by the system are)");
  508.  
  509.   if (NULL == psidOwner)
  510.   { printf("\nSD's Owner is NULL, so SE_OWNER_DEFAULTED is ignored");
  511.   }
  512.   else
  513.   { printf("\nSD's Owner is Not NULL");
  514.     if (bOwnerDefaulted )
  515.     { printf("\nSD's Owner was assigned by a default mechanism");
  516.     }
  517.     else
  518.     { printf("\nSD's Owner was Not assigned by a default mechanism");
  519.     }
  520.     if(!LookupSIDName(psidOwner,""))
  521.     { PERR("LookupSIDName failed");
  522.     }
  523.   }
  524.  
  525.   /**************************************************************************\
  526.   *
  527.   * The other use for psidGroup is for Macintosh client support
  528.   *
  529.   \**************************************************************************/
  530.  
  531.   if (NULL == psidGroup)
  532.   { printf("\nSD's Group is NULL, so SE_GROUP_DEFAULTED is ignored");
  533.     printf("\nSD's Group being NULL is typical, GROUP in SD(s) is mainly for POSIX compliance");
  534.   }
  535.   else
  536.   { if (bGroupDefaulted)
  537.     { printf("\nSD's Group was assigned by a default mechanism");
  538.     }
  539.     else
  540.     { printf("\nSD's Group was Not assigned by a default mechanism");
  541.     }
  542.     if(!LookupSIDName(psidGroup,""))
  543.     { PERR("LookupSIDName failed");
  544.     }
  545.   }
  546.  
  547.   if   (SE_DACL_PRESENT & sdcSDControl)
  548.   { printf("\nSD's DACL is Present");
  549.     if (bDaclDefaulted)
  550.     { printf("\nSD's DACL was assigned by a default mechanism");
  551.     }
  552.     else
  553.     { printf("\nSD's DACL was Not assigned by a default mechanism");
  554.     }
  555.  
  556.     if (NULL == paclDACL)
  557.     { printf("\nSD has a NULL DACL explicitly specified      (allows all access to Everyone)");
  558.       printf("\n    This does not apply to this SD, but for comparison,");
  559.       printf("\n    a non-NULL DACL pointer to a 0-length ACL allows  no access to   anyone");
  560.     }
  561.     else if(!ExamineACL(paclDACL,"",kamKindOfMask))
  562.     {  PERR("ExamineACL failed");
  563.     }
  564.   }
  565.   else
  566.   { printf("\nSD's DACL is Not Present, so SE_DACL_DEFAULTED is ignored");
  567.     printf("\nSD has no DACL at all (allows all access to Everyone)");
  568.   }
  569.  
  570.   if   (SE_SACL_PRESENT & sdcSDControl)
  571.   { printf("\nSD's SACL is Present");
  572.     if (bSaclDefaulted)
  573.     { printf("\nSD's SACL was assigned by a default mechanism");
  574.     }
  575.     else
  576.     { printf("\nSD's SACL was Not assigned by a default mechanism");
  577.     }
  578.  
  579.     if (NULL == paclSACL)
  580.     { printf("\nSD has a NULL SACL explicitly specified");
  581.     }
  582.     else if(!ExamineACL(paclSACL,"",kamKindOfMask))
  583.     {  PERR("ExamineACL failed");
  584.     }
  585.   }
  586.   else
  587.   { printf("\nSD's SACL is Not Present, so SE_SACL_DEFAULTED is ignored");
  588.     printf("\nSD has no SACL at all (or we did not request to see it)");
  589.   }
  590. }
  591.  
  592. /****************************************************************************\
  593. *
  594. * FUNCTION: ExamineACL
  595. *
  596. \****************************************************************************/
  597.  
  598. BOOL ExamineACL   (PACL paclACL,              LPTSTR lpszOldIndent,
  599.                    KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask)
  600. {
  601.   #define                          SZ_INDENT_BUF 80
  602.   UCHAR                ucIndentBuf[SZ_INDENT_BUF] = "";
  603.   ACL_SIZE_INFORMATION                      asiAclSize;
  604.   DWORD                dwBufLength = sizeof(asiAclSize);
  605.   DWORD                dwAcl_i;
  606.   ACCESS_ALLOWED_ACE   *paaAllowedAce;
  607.  
  608.   strcpy(ucIndentBuf,lpszOldIndent);
  609.   strcat(ucIndentBuf,"  ");
  610.  
  611.   if (!IsValidAcl(paclACL))
  612.   { PERR("IsValidAcl");
  613.     return(FALSE);
  614.   }
  615.  
  616.   if (!GetAclInformation(paclACL,
  617.                          (LPVOID)&asiAclSize,
  618.                          (DWORD)dwBufLength,
  619.                          (ACL_INFORMATION_CLASS)AclSizeInformation))
  620.   { PERR("GetAclInformation");
  621.     return(FALSE);
  622.   }
  623.  
  624.   printf("\n%sACL has %d ACE(s)",ucIndentBuf,asiAclSize.AceCount);
  625.  
  626.   for (dwAcl_i = 0; dwAcl_i < asiAclSize.AceCount;  dwAcl_i++)
  627.   {
  628.     if (!GetAce(paclACL,
  629.                 dwAcl_i,
  630.                 (LPVOID *)&paaAllowedAce))
  631.     { PERR("GetAce");
  632.       return(FALSE);
  633.     }
  634.     switch (paaAllowedAce->Header.AceType)
  635.     {
  636.       case                       ACCESS_ALLOWED_ACE_TYPE :
  637.       { printf("\n%sACE %d is an ACCESS_ALLOWED_ACE_TYPE",ucIndentBuf,dwAcl_i);
  638.         break;
  639.       }
  640.       case                       ACCESS_DENIED_ACE_TYPE :
  641.       { printf("\n%sACE %d is an ACCESS_DENIED_ACE_TYPE",ucIndentBuf,dwAcl_i);
  642.         break;
  643.       }
  644.       case                       SYSTEM_AUDIT_ACE_TYPE :
  645.       { printf("\n%sACE %d is a  SYSTEM_AUDIT_ACE_TYPE",ucIndentBuf,dwAcl_i);
  646.         break;
  647.       }
  648.       case                       SYSTEM_ALARM_ACE_TYPE :
  649.       { printf("\n%sACE %d is a  SYSTEM_ALARM_ACE_TYPE",ucIndentBuf,dwAcl_i);
  650.         break;
  651.       }
  652.       default :
  653.       { printf("\n%sACE %d is an IMPOSSIBLE ACE_TYPE!!! Run debugger, examine value!",ucIndentBuf,dwAcl_i);
  654.         return(FALSE);
  655.       }
  656.     }
  657.  
  658.     printf("\n%sACE %d mask               == 0x%.8x",ucIndentBuf,dwAcl_i,paaAllowedAce->Mask);
  659.  
  660.     ExamineMask(paaAllowedAce->Mask,ucIndentBuf,kamKindOfMask);
  661.  
  662.     if(!LookupSIDName((PSID)&(paaAllowedAce->SidStart),ucIndentBuf))
  663.     { PERR("LookupSIDName failed");
  664.     }
  665.   }
  666. }
  667.  
  668. /****************************************************************************\
  669. *
  670. * FUNCTION: ExamineMask
  671. *
  672. \****************************************************************************/
  673.  
  674. VOID ExamineMask  (ACCESS_MASK amMask,        LPTSTR lpszOldIndent,
  675.                    KINDS_OF_ACCESSMASKS_DECODED kamKindOfMask)
  676. {
  677.   #define STANDARD_RIGHTS_ALL_THE_BITS 0x00FF0000L
  678.   #define GENERIC_RIGHTS_ALL_THE_BITS  0xF0000000L
  679.   UCHAR ucIndentBuf[SZ_INDENT_BUF]     = "";
  680.   UCHAR ucIndentBitsBuf[SZ_INDENT_BUF] = "";
  681.   DWORD dwGenericBits;
  682.   DWORD dwStandardBits;
  683.   DWORD dwSpecificBits;
  684.   DWORD dwAccessSystemSecurityBit;
  685.   DWORD dwExtraBits;
  686.  
  687.   strcpy(ucIndentBuf,    lpszOldIndent);
  688.   strcat(ucIndentBuf,    "  ");
  689.   strcpy(ucIndentBitsBuf,lpszOldIndent);
  690.   strcat(ucIndentBitsBuf,"                            ");
  691.  
  692.   dwStandardBits            = (amMask & STANDARD_RIGHTS_ALL_THE_BITS);
  693.   dwSpecificBits            = (amMask & SPECIFIC_RIGHTS_ALL         );
  694.   dwAccessSystemSecurityBit = (amMask & ACCESS_SYSTEM_SECURITY      );
  695.   dwGenericBits             = (amMask & GENERIC_RIGHTS_ALL_THE_BITS );
  696.  
  697.   /**************************************************************************\
  698.   *
  699.   * Print then decode the standard rights bits
  700.   *
  701.   \**************************************************************************/
  702.  
  703.   printf("\n%sStandard Rights        == 0x%.8x",ucIndentBuf,dwStandardBits);
  704.  
  705.   if (dwStandardBits)
  706.   {
  707.     if ((dwStandardBits    & DELETE                  ) == DELETE                  )
  708.     { printf("\n%s0x00010000 DELETE                  ",ucIndentBitsBuf);
  709.     }
  710.     if ((dwStandardBits    & READ_CONTROL            ) == READ_CONTROL            )
  711.     { printf("\n%s0x00020000 READ_CONTROL            ",ucIndentBitsBuf);
  712.     }
  713.     if ((dwStandardBits    & STANDARD_RIGHTS_READ    ) == STANDARD_RIGHTS_READ    )
  714.     { printf("\n%s0x00020000 STANDARD_RIGHTS_READ    ",ucIndentBitsBuf);
  715.     }
  716.     if ((dwStandardBits    & STANDARD_RIGHTS_WRITE   ) == STANDARD_RIGHTS_WRITE   )
  717.     { printf("\n%s0x00020000 STANDARD_RIGHTS_WRITE   ",ucIndentBitsBuf);
  718.     }
  719.     if ((dwStandardBits    & STANDARD_RIGHTS_EXECUTE ) == STANDARD_RIGHTS_EXECUTE )
  720.     { printf("\n%s0x00020000 STANDARD_RIGHTS_EXECUTE ",ucIndentBitsBuf);
  721.     }
  722.     if ((dwStandardBits    & WRITE_DAC               ) == WRITE_DAC               )
  723.     { printf("\n%s0x00040000 WRITE_DAC               ",ucIndentBitsBuf);
  724.     }
  725.     if ((dwStandardBits    & WRITE_OWNER             ) == WRITE_OWNER             )
  726.     { printf("\n%s0x00080000 WRITE_OWNER             ",ucIndentBitsBuf);
  727.     }
  728.     if ((dwStandardBits    & SYNCHRONIZE             ) == SYNCHRONIZE             )
  729.     { printf("\n%s0x00100000 SYNCHRONIZE             ",ucIndentBitsBuf);
  730.     }
  731.     if ((dwStandardBits    & STANDARD_RIGHTS_REQUIRED) == STANDARD_RIGHTS_REQUIRED)
  732.     { printf("\n%s0x000F0000 STANDARD_RIGHTS_REQUIRED",ucIndentBitsBuf);
  733.     }
  734.     if ((dwStandardBits    & STANDARD_RIGHTS_ALL     ) == STANDARD_RIGHTS_ALL     )
  735.     { printf("\n%s0x001F0000 STANDARD_RIGHTS_ALL     ",ucIndentBitsBuf);
  736.     }
  737.  
  738.     dwExtraBits = dwStandardBits & ( ~( DELETE
  739.                                       | READ_CONTROL
  740.                                       | STANDARD_RIGHTS_READ
  741.                                       | STANDARD_RIGHTS_WRITE
  742.                                       | STANDARD_RIGHTS_EXECUTE
  743.                                       | WRITE_DAC
  744.                                       | WRITE_OWNER
  745.                                       | SYNCHRONIZE
  746.                                       | STANDARD_RIGHTS_REQUIRED
  747.                                       | STANDARD_RIGHTS_ALL) );
  748.     if (dwExtraBits)
  749.     { printf("\n%sExtra standard bits    == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
  750.     }
  751.   }
  752.  
  753.   /**************************************************************************\
  754.   *
  755.   * Print then decode the specific rights bits
  756.   *
  757.   \**************************************************************************/
  758.  
  759.   printf("\n%sSpecific Rights        == 0x%.8x",ucIndentBuf,dwSpecificBits);
  760.  
  761.   if (dwSpecificBits)
  762.   {
  763.     if      (FileAccessMask          == kamKindOfMask)
  764.     {
  765.       if ((dwSpecificBits    & FILE_READ_DATA           ) == FILE_READ_DATA           )
  766.       { printf("\n%s0x00000001 FILE_READ_DATA            (file & pipe)     ",ucIndentBitsBuf);
  767.       }
  768.       if ((dwSpecificBits    & FILE_LIST_DIRECTORY      ) == FILE_LIST_DIRECTORY      )
  769.       { printf("\n%s0x00000001 FILE_LIST_DIRECTORY       (directory)       ",ucIndentBitsBuf);
  770.       }
  771.       if ((dwSpecificBits    & FILE_WRITE_DATA          ) == FILE_WRITE_DATA          )
  772.       { printf("\n%s0x00000002 FILE_WRITE_DATA           (file & pipe)     ",ucIndentBitsBuf);
  773.       }
  774.       if ((dwSpecificBits    & FILE_ADD_FILE            ) == FILE_ADD_FILE            )
  775.       { printf("\n%s0x00000002 FILE_ADD_FILE             (directory)       ",ucIndentBitsBuf);
  776.       }
  777.       if ((dwSpecificBits    & FILE_APPEND_DATA         ) == FILE_APPEND_DATA         )
  778.       { printf("\n%s0x00000004 FILE_APPEND_DATA          (file)            ",ucIndentBitsBuf);
  779.       }
  780.       if ((dwSpecificBits    & FILE_ADD_SUBDIRECTORY    ) == FILE_ADD_SUBDIRECTORY    )
  781.       { printf("\n%s0x00000004 FILE_ADD_SUBDIRECTORY     (directory)       ",ucIndentBitsBuf);
  782.       }
  783.       if ((dwSpecificBits    & FILE_CREATE_PIPE_INSTANCE) == FILE_CREATE_PIPE_INSTANCE)
  784.       { printf("\n%s0x00000004 FILE_CREATE_PIPE_INSTANCE (named pipe)      ",ucIndentBitsBuf);
  785.       }
  786.       if ((dwSpecificBits    & FILE_READ_EA             ) == FILE_READ_EA             )
  787.       { printf("\n%s0x00000008 FILE_READ_EA              (file & directory)",ucIndentBitsBuf);
  788.       }
  789.       if ((dwSpecificBits    & FILE_WRITE_EA            ) == FILE_WRITE_EA            )
  790.       { printf("\n%s0x00000010 FILE_WRITE_EA             (file & directory)",ucIndentBitsBuf);
  791.       }
  792.       if ((dwSpecificBits    & FILE_EXECUTE             ) == FILE_EXECUTE             )
  793.       { printf("\n%s0x00000020 FILE_EXECUTE              (file)            ",ucIndentBitsBuf);
  794.       }
  795.       if ((dwSpecificBits    & FILE_TRAVERSE            ) == FILE_TRAVERSE            )
  796.       { printf("\n%s0x00000020 FILE_TRAVERSE             (directory)       ",ucIndentBitsBuf);
  797.       }
  798.       if ((dwSpecificBits    & FILE_DELETE_CHILD        ) == FILE_DELETE_CHILD        )
  799.       { printf("\n%s0x00000040 FILE_DELETE_CHILD         (directory)       ",ucIndentBitsBuf);
  800.       }
  801.       if ((dwSpecificBits    & FILE_READ_ATTRIBUTES     ) == FILE_READ_ATTRIBUTES     )
  802.       { printf("\n%s0x00000080 FILE_READ_ATTRIBUTES      (all)             ",ucIndentBitsBuf);
  803.       }
  804.       if ((dwSpecificBits    & FILE_WRITE_ATTRIBUTES    ) == FILE_WRITE_ATTRIBUTES    )
  805.       { printf("\n%s0x00000100 FILE_WRITE_ATTRIBUTES     (all)             ",ucIndentBitsBuf);
  806.       }
  807.  
  808.       if (((dwStandardBits | dwSpecificBits   )
  809.            & FILE_ALL_ACCESS     ) == FILE_ALL_ACCESS     )
  810.       { printf("\n%s0x001F01FF FILE_ALL_ACCESS      == (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x1FF)",ucIndentBitsBuf);
  811.       }
  812.       if (((dwStandardBits | dwSpecificBits   )
  813.            & FILE_GENERIC_READ   ) == FILE_GENERIC_READ   )
  814.       { printf("\n%s0x00120089 FILE_GENERIC_READ    == (STANDARD_RIGHTS_READ | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA | SYNCHRONIZE)",ucIndentBitsBuf);
  815.       }
  816.       if (((dwStandardBits | dwSpecificBits   )
  817.            & FILE_GENERIC_WRITE  ) == FILE_GENERIC_WRITE  )
  818.       { printf("\n%s0x00120116 FILE_GENERIC_WRITE   == (STANDARD_RIGHTS_WRITE | FILE_WRITE_DATA | FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_APPEND_DATA | SYNCHRONIZE)",ucIndentBitsBuf);
  819.       }
  820.       if (((dwStandardBits | dwSpecificBits   )
  821.            & FILE_GENERIC_EXECUTE) == FILE_GENERIC_EXECUTE)
  822.       { printf("\n%s0x001200A0 FILE_GENERIC_EXECUTE == (STANDARD_RIGHTS_EXECUTE | FILE_READ_ATTRIBUTES | FILE_EXECUTE | SYNCHRONIZE)",ucIndentBitsBuf);
  823.       }
  824.  
  825.       dwExtraBits = dwSpecificBits & ( ~( FILE_READ_DATA
  826.                                         | FILE_LIST_DIRECTORY
  827.                                         | FILE_WRITE_DATA
  828.                                         | FILE_ADD_FILE
  829.                                         | FILE_APPEND_DATA
  830.                                         | FILE_ADD_SUBDIRECTORY
  831.                                         | FILE_CREATE_PIPE_INSTANCE
  832.                                         | FILE_READ_EA
  833.                                         | FILE_WRITE_EA
  834.                                         | FILE_EXECUTE
  835.                                         | FILE_TRAVERSE
  836.                                         | FILE_DELETE_CHILD
  837.                                         | FILE_READ_ATTRIBUTES
  838.                                         | FILE_WRITE_ATTRIBUTES
  839.                                         | (FILE_ALL_ACCESS      & SPECIFIC_RIGHTS_ALL)
  840.                                         | (FILE_GENERIC_READ    & SPECIFIC_RIGHTS_ALL)
  841.                                         | (FILE_GENERIC_WRITE   & SPECIFIC_RIGHTS_ALL)
  842.                                         | (FILE_GENERIC_EXECUTE & SPECIFIC_RIGHTS_ALL) ) );
  843.       if (dwExtraBits)
  844.       { printf("\n%sExtra specific bits    == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
  845.       }
  846.     }
  847.     else if (ProcessAccessMask       == kamKindOfMask)
  848.     {
  849.       if ((dwSpecificBits    & PROCESS_TERMINATE        ) == PROCESS_TERMINATE        )
  850.       { printf("\n%s0x00000001 PROCESS_TERMINATE        ",ucIndentBitsBuf);
  851.       }
  852.       if ((dwSpecificBits    & PROCESS_CREATE_THREAD    ) == PROCESS_CREATE_THREAD    )
  853.       { printf("\n%s0x00000002 PROCESS_CREATE_THREAD    ",ucIndentBitsBuf);
  854.       }
  855.       if ((dwSpecificBits    & PROCESS_VM_OPERATION     ) == PROCESS_VM_OPERATION     )
  856.       { printf("\n%s0x00000008 PROCESS_VM_OPERATION     ",ucIndentBitsBuf);
  857.       }
  858.       if ((dwSpecificBits    & PROCESS_VM_READ          ) == PROCESS_VM_READ          )
  859.       { printf("\n%s0x00000010 PROCESS_VM_READ          ",ucIndentBitsBuf);
  860.       }
  861.       if ((dwSpecificBits    & PROCESS_VM_WRITE         ) == PROCESS_VM_WRITE         )
  862.       { printf("\n%s0x00000020 PROCESS_VM_WRITE         ",ucIndentBitsBuf);
  863.       }
  864.       if ((dwSpecificBits    & PROCESS_DUP_HANDLE       ) == PROCESS_DUP_HANDLE       )
  865.       { printf("\n%s0x00000040 PROCESS_DUP_HANDLE       ",ucIndentBitsBuf);
  866.       }
  867.       if ((dwSpecificBits    & PROCESS_CREATE_PROCESS   ) == PROCESS_CREATE_PROCESS   )
  868.       { printf("\n%s0x00000080 PROCESS_CREATE_PROCESS   ",ucIndentBitsBuf);
  869.       }
  870.       if ((dwSpecificBits    & PROCESS_SET_INFORMATION  ) == PROCESS_SET_INFORMATION  )
  871.       { printf("\n%s0x00000200 PROCESS_SET_INFORMATION  ",ucIndentBitsBuf);
  872.       }
  873.       if ((dwSpecificBits    & PROCESS_QUERY_INFORMATION) == PROCESS_QUERY_INFORMATION)
  874.       { printf("\n%s0x00000400 PROCESS_QUERY_INFORMATION",ucIndentBitsBuf);
  875.       }
  876.  
  877.       if (((dwStandardBits | dwSpecificBits )
  878.            & PROCESS_ALL_ACCESS) == PROCESS_ALL_ACCESS)
  879.       { printf("\n%s0x001F0FFF PROCESS_ALL_ACCESS == (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | 0x00000FFF) ",ucIndentBitsBuf);
  880.       }
  881.  
  882.       dwExtraBits = dwSpecificBits & ( ~( PROCESS_TERMINATE
  883.                                         | PROCESS_CREATE_THREAD
  884.                                         | PROCESS_VM_OPERATION
  885.                                         | PROCESS_VM_READ
  886.                                         | PROCESS_VM_WRITE
  887.                                         | PROCESS_DUP_HANDLE
  888.                                         | PROCESS_CREATE_PROCESS
  889.                                         | PROCESS_SET_INFORMATION
  890.                                         | PROCESS_QUERY_INFORMATION
  891.                                         | (PROCESS_ALL_ACCESS & SPECIFIC_RIGHTS_ALL) ) );
  892.       if (dwExtraBits)
  893.       { printf("\n%sExtra specific bits    == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
  894.       }
  895.     }
  896.     else if (WindowStationAccessMask == kamKindOfMask)
  897.     {
  898.       if ((dwSpecificBits    & WINSTA_ENUMDESKTOPS     ) == WINSTA_ENUMDESKTOPS     )
  899.       { printf("\n%s0x00000001 WINSTA_ENUMDESKTOPS     ",ucIndentBitsBuf);
  900.       }
  901.       if ((dwSpecificBits    & WINSTA_READATTRIBUTES   ) == WINSTA_READATTRIBUTES   )
  902.       { printf("\n%s0x00000002 WINSTA_READATTRIBUTES   ",ucIndentBitsBuf);
  903.       }
  904.       if ((dwSpecificBits    & WINSTA_ACCESSCLIPBOARD  ) == WINSTA_ACCESSCLIPBOARD  )
  905.       { printf("\n%s0x00000004 WINSTA_ACCESSCLIPBOARD  ",ucIndentBitsBuf);
  906.       }
  907.       if ((dwSpecificBits    & WINSTA_CREATEDESKTOP    ) == WINSTA_CREATEDESKTOP    )
  908.       { printf("\n%s0x00000008 WINSTA_CREATEDESKTOP    ",ucIndentBitsBuf);
  909.       }
  910.       if ((dwSpecificBits    & WINSTA_WRITEATTRIBUTES  ) == WINSTA_WRITEATTRIBUTES  )
  911.       { printf("\n%s0x00000010 WINSTA_WRITEATTRIBUTES  ",ucIndentBitsBuf);
  912.       }
  913.       if ((dwSpecificBits    & WINSTA_ACCESSGLOBALATOMS) == WINSTA_ACCESSGLOBALATOMS)
  914.       { printf("\n%s0x00000020 WINSTA_ACCESSGLOBALATOMS",ucIndentBitsBuf);
  915.       }
  916.       if ((dwSpecificBits    & WINSTA_EXITWINDOWS      ) == WINSTA_EXITWINDOWS      )
  917.       { printf("\n%s0x00000040 WINSTA_EXITWINDOWS      ",ucIndentBitsBuf);
  918.       }
  919.       if ((dwSpecificBits    & WINSTA_ENUMERATE        ) == WINSTA_ENUMERATE        )
  920.       { printf("\n%s0x00000100 WINSTA_ENUMERATE        ",ucIndentBitsBuf);
  921.       }
  922.       if ((dwSpecificBits    & WINSTA_READSCREEN       ) == WINSTA_READSCREEN       )
  923.       { printf("\n%s0x00000200 WINSTA_READSCREEN       ",ucIndentBitsBuf);
  924.       }
  925.  
  926.       dwExtraBits = dwSpecificBits & ( ~( WINSTA_ENUMDESKTOPS
  927.                                         | WINSTA_READATTRIBUTES
  928.                                         | WINSTA_ACCESSCLIPBOARD
  929.                                         | WINSTA_CREATEDESKTOP
  930.                                         | WINSTA_WRITEATTRIBUTES
  931.                                         | WINSTA_ACCESSGLOBALATOMS
  932.                                         | WINSTA_EXITWINDOWS
  933.                                         | WINSTA_ENUMERATE
  934.                                         | WINSTA_READSCREEN) );
  935.       if (dwExtraBits)
  936.       { printf("\n%sExtra specific bits    == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
  937.       }
  938.     }
  939.     else if (RegKeyAccessMask        == kamKindOfMask)
  940.     {
  941.       if ((dwSpecificBits    & KEY_QUERY_VALUE       ) == KEY_QUERY_VALUE       )
  942.       { printf("\n%s0x00000001 KEY_QUERY_VALUE       ",ucIndentBitsBuf);
  943.       }
  944.       if ((dwSpecificBits    & KEY_SET_VALUE         ) == KEY_SET_VALUE         )
  945.       { printf("\n%s0x00000002 KEY_SET_VALUE         ",ucIndentBitsBuf);
  946.       }
  947.       if ((dwSpecificBits    & KEY_CREATE_SUB_KEY    ) == KEY_CREATE_SUB_KEY    )
  948.       { printf("\n%s0x00000004 KEY_CREATE_SUB_KEY    ",ucIndentBitsBuf);
  949.       }
  950.       if ((dwSpecificBits    & KEY_ENUMERATE_SUB_KEYS) == KEY_ENUMERATE_SUB_KEYS)
  951.       { printf("\n%s0x00000008 KEY_ENUMERATE_SUB_KEYS",ucIndentBitsBuf);
  952.       }
  953.       if ((dwSpecificBits    & KEY_NOTIFY            ) == KEY_NOTIFY            )
  954.       { printf("\n%s0x00000010 KEY_NOTIFY            ",ucIndentBitsBuf);
  955.       }
  956.       if ((dwSpecificBits    & KEY_CREATE_LINK       ) == KEY_CREATE_LINK       )
  957.       { printf("\n%s0x00000020 KEY_CREATE_LINK       ",ucIndentBitsBuf);
  958.       }
  959.  
  960.       if (((dwStandardBits | dwSpecificBits   )
  961.            & KEY_READ      ) == KEY_READ      )
  962.       { printf("\n%s0x00020019 KEY_READ       == ((STANDARD_RIGHTS_READ | KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY) & (~SYNCHRONIZE))",ucIndentBitsBuf);
  963.       }
  964.       if (((dwStandardBits | dwSpecificBits   )
  965.            & KEY_WRITE     ) == KEY_WRITE     )
  966.       { printf("\n%s0x00020006 KEY_WRITE      == ((STANDARD_RIGHTS_WRITE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY) & (~SYNCHRONIZE))",ucIndentBitsBuf);
  967.       }
  968.       if (((dwStandardBits | dwSpecificBits   )
  969.            & KEY_EXECUTE   ) == KEY_EXECUTE   )
  970.       { printf("\n%s0x00020019 KEY_EXECUTE    == ((KEY_READ) & (~SYNCHRONIZE))",ucIndentBitsBuf);
  971.       }
  972.       if (((dwStandardBits | dwSpecificBits   )
  973.            & KEY_ALL_ACCESS) == KEY_ALL_ACCESS)
  974.       { printf("\n%s0x000F003F KEY_ALL_ACCESS == ((STANDARD_RIGHTS_ALL | KEY_QUERY_VALUE | KEY_SET_VALUE | KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS | KEY_NOTIFY | KEY_CREATE_LINK) & (~SYNCHRONIZE))",ucIndentBitsBuf);
  975.       }
  976.  
  977.       dwExtraBits = dwSpecificBits & ( ~( KEY_QUERY_VALUE
  978.                                         | KEY_SET_VALUE
  979.                                         | KEY_CREATE_SUB_KEY
  980.                                         | KEY_ENUMERATE_SUB_KEYS
  981.                                         | KEY_NOTIFY
  982.                                         | KEY_CREATE_LINK
  983.                                         | (KEY_READ       & SPECIFIC_RIGHTS_ALL)
  984.                                         | (KEY_WRITE      & SPECIFIC_RIGHTS_ALL)
  985.                                         | (KEY_EXECUTE    & SPECIFIC_RIGHTS_ALL)
  986.                                         | (KEY_ALL_ACCESS & SPECIFIC_RIGHTS_ALL) ) );
  987.       if (dwExtraBits)
  988.       { printf("\n%sExtra specific bits    == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
  989.       }
  990.     }
  991.     else if (ServiceAccessMask       == kamKindOfMask)
  992.     {
  993.       if ((dwSpecificBits    & SERVICE_QUERY_CONFIG        ) == SERVICE_QUERY_CONFIG        )
  994.       { printf("\n%s0x00000001 SERVICE_QUERY_CONFIG        ",ucIndentBitsBuf);
  995.       }
  996.       if ((dwSpecificBits    & SERVICE_CHANGE_CONFIG       ) == SERVICE_CHANGE_CONFIG       )
  997.       { printf("\n%s0x00000002 SERVICE_CHANGE_CONFIG       ",ucIndentBitsBuf);
  998.       }
  999.       if ((dwSpecificBits    & SERVICE_QUERY_STATUS        ) == SERVICE_QUERY_STATUS        )
  1000.       { printf("\n%s0x00000004 SERVICE_QUERY_STATUS        ",ucIndentBitsBuf);
  1001.       }
  1002.       if ((dwSpecificBits    & SERVICE_ENUMERATE_DEPENDENTS) == SERVICE_ENUMERATE_DEPENDENTS)
  1003.       { printf("\n%s0x00000008 SERVICE_ENUMERATE_DEPENDENTS",ucIndentBitsBuf);
  1004.       }
  1005.       if ((dwSpecificBits    & SERVICE_START               ) == SERVICE_START               )
  1006.       { printf("\n%s0x00000010 SERVICE_START               ",ucIndentBitsBuf);
  1007.       }
  1008.       if ((dwSpecificBits    & SERVICE_STOP                ) == SERVICE_STOP                )
  1009.       { printf("\n%s0x00000020 SERVICE_STOP                ",ucIndentBitsBuf);
  1010.       }
  1011.       if ((dwSpecificBits    & SERVICE_PAUSE_CONTINUE      ) == SERVICE_PAUSE_CONTINUE      )
  1012.       { printf("\n%s0x00000040 SERVICE_PAUSE_CONTINUE      ",ucIndentBitsBuf);
  1013.       }
  1014.       if ((dwSpecificBits    & SERVICE_INTERROGATE         ) == SERVICE_INTERROGATE         )
  1015.       { printf("\n%s0x00000080 SERVICE_INTERROGATE         ",ucIndentBitsBuf);
  1016.       }
  1017.       if ((dwSpecificBits    & SERVICE_USER_DEFINED_CONTROL) == SERVICE_USER_DEFINED_CONTROL)
  1018.       { printf("\n%s0x00000100 SERVICE_USER_DEFINED_CONTROL",ucIndentBitsBuf,ucIndentBitsBuf);
  1019.       }
  1020.  
  1021.       if (((dwStandardBits | dwSpecificBits )
  1022.            & SERVICE_ALL_ACCESS) == SERVICE_ALL_ACCESS)
  1023.       { printf("\n%s0x000F01FF SERVICE_ALL_ACCESS == (STANDARD_RIGHTS_REQUIRED | SERVICE_QUERY_CONFIG | SERVICE_CHANGE_CONFIG | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS | SERVICE_START | SERVICE_STOP | SERVICE_PAUSE_CONTINUE | SERVICE_INTERROGATE | SERVICE_USER_DEFINED_CONTROL)",ucIndentBitsBuf);
  1024.       }
  1025.  
  1026.       dwExtraBits = dwSpecificBits & ( ~( SERVICE_QUERY_CONFIG
  1027.                                         | SERVICE_CHANGE_CONFIG
  1028.                                         | SERVICE_QUERY_STATUS
  1029.                                         | SERVICE_ENUMERATE_DEPENDENTS
  1030.                                         | SERVICE_START
  1031.                                         | SERVICE_STOP
  1032.                                         | SERVICE_PAUSE_CONTINUE
  1033.                                         | SERVICE_INTERROGATE
  1034.                                         | SERVICE_USER_DEFINED_CONTROL
  1035.                                         | (SERVICE_ALL_ACCESS & SPECIFIC_RIGHTS_ALL) ) );
  1036.       if (dwExtraBits)
  1037.       { printf("\n%sExtra specific bits    == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
  1038.       }
  1039.     }
  1040.     else if (DefaultDaclInAccesTokenAccessMask == kamKindOfMask)
  1041.     {
  1042.       printf("\n%sSpecific bits in default Dacl(s) in token not broken down into defines",ucIndentBitsBuf);
  1043.     }
  1044.     else
  1045.     { printf("\n%sYou will need to write some code (such as that directly",ucIndentBuf);
  1046.       printf("\n%s  above the code that wrote out this message) to decode",ucIndentBuf);
  1047.       printf("\n%s  this kind of access mask",ucIndentBuf);
  1048.     }
  1049.   }
  1050.  
  1051.   /**************************************************************************\
  1052.   *
  1053.   * Print then decode the ACCESS_SYSTEM_SECURITY bit
  1054.   *
  1055.   \**************************************************************************/
  1056.  
  1057.   printf("\n%sAccess System Security == 0x%.8x",ucIndentBuf,dwAccessSystemSecurityBit);
  1058.  
  1059.   /**************************************************************************\
  1060.   *
  1061.   * Print then decode the generic rights bits, which will rarely be on
  1062.   *
  1063.   * Generic bits are nearly always mapped by Windows NT before it tries to do
  1064.   *   anything with them.  You can ignore the fact that generic bits are
  1065.   *   special in any way, although it helps to keep track of what the mappings
  1066.   *   are so that you don't have any surprises
  1067.   *
  1068.   * The only time the generic bits are not mapped immediately is if they are
  1069.   *   placed in an inheritable ACE in an ACL.  In that case they're mapped
  1070.   *   when the child object is created
  1071.   *
  1072.   \**************************************************************************/
  1073.  
  1074.   printf("\n%sGeneric  Rights        == 0x%.8x",ucIndentBuf,dwGenericBits);
  1075.  
  1076.   if (dwGenericBits)
  1077.   {
  1078.     if ((dwGenericBits     & GENERIC_READ   ) == GENERIC_READ   )
  1079.     { printf("\n%s0x80000000 GENERIC_READ   ",ucIndentBitsBuf);
  1080.     }
  1081.     if ((dwGenericBits     & GENERIC_WRITE  ) == GENERIC_WRITE  )
  1082.     { printf("\n%s0x40000000 GENERIC_WRITE  ",ucIndentBitsBuf);
  1083.     }
  1084.     if ((dwGenericBits     & GENERIC_EXECUTE) == GENERIC_EXECUTE)
  1085.     { printf("\n%s0x20000000 GENERIC_EXECUTE",ucIndentBitsBuf);
  1086.     }
  1087.     if ((dwGenericBits     & GENERIC_ALL    ) == GENERIC_ALL    )
  1088.     { printf("\n%s0x10000000 GENERIC_ALL    ",ucIndentBitsBuf);
  1089.     }
  1090.  
  1091.     dwExtraBits = dwGenericBits & ( ~( GENERIC_READ
  1092.                                      | GENERIC_WRITE
  1093.                                      | GENERIC_EXECUTE
  1094.                                      | GENERIC_ALL) );
  1095.     if (dwExtraBits)
  1096.     { printf("\n%sExtra generic bits     == 0x%.8x <-This is a problem, should be all 0s",ucIndentBuf,dwExtraBits);
  1097.     }
  1098.   }
  1099. }
  1100.  
  1101. /****************************************************************************\
  1102. *
  1103. * FUNCTION: LookupSIDName
  1104. *
  1105. \****************************************************************************/
  1106.  
  1107. BOOL LookupSIDName(PSID psidSID, LPTSTR lpszOldIndent)
  1108. {
  1109.   UCHAR        ucIndentBuf    [SZ_INDENT_BUF]    = "";
  1110.   #define                      SZ_ACCT_NAME_BUF  60
  1111.   UCHAR        ucNameBuf      [SZ_ACCT_NAME_BUF] = "";
  1112.   DWORD        dwNameLength  = SZ_ACCT_NAME_BUF;
  1113.   #define                      SZ_DMN_NAME_BUF   60
  1114.   UCHAR        ucDomainNmBuf  [SZ_DMN_NAME_BUF]  = "";
  1115.   DWORD        dwDNameLength = SZ_DMN_NAME_BUF;
  1116.   #define                      SZ_SID_STRING_BUF 150
  1117.   UCHAR        ucSIDStringBuf [SZ_SID_STRING_BUF] = "";
  1118.   SID_NAME_USE peAcctNameUse = SidTypeInvalid;
  1119.   DWORD        dwLookupStatus;
  1120.   BOOL         bGotBadLookupThatIsNotLocalLogonSID;
  1121.  
  1122.   strcpy(ucIndentBuf,lpszOldIndent);
  1123.   strcat(ucIndentBuf,"  ");
  1124.  
  1125.   if (!IsValidSid(psidSID))
  1126.   { PERR("IsValidSid");
  1127.     return(FALSE);
  1128.   }
  1129.  
  1130.   if (!SIDStringName(psidSID,ucSIDStringBuf))
  1131.   { PERR("SIDStringName");
  1132.     return(FALSE);
  1133.   }
  1134.  
  1135.   if (!LookupAccountSid(
  1136.          (LPTSTR)"",         // Look on local machine
  1137.          psidSID,
  1138.          (LPTSTR)&ucNameBuf,
  1139.          (LPDWORD)&dwNameLength,
  1140.          (LPTSTR)&ucDomainNmBuf,
  1141.          (LPDWORD)&dwDNameLength,
  1142.          (PSID_NAME_USE)&peAcctNameUse))
  1143.   {
  1144.     dwLookupStatus = GetLastError();
  1145.  
  1146.     /************************************************************************\
  1147.     *
  1148.     * Got a bad Lookup, so check is SID the Local Logon SID?
  1149.     *
  1150.     * The problem is that LookupAccountSid api will find all the well-known
  1151.     *   SIDs except the Local Logon SID.  The last two sub-authorities are
  1152.     *   always different, so to check to see if the SID we're looking at is
  1153.     *   the Local Logon SID, we take the psidLogonIdsSid variable we built at
  1154.     *   initialization time, and blast into it's last two sub-authorities the
  1155.     *   last two sub-authorities that we have.  Then compare for EqualSid
  1156.     *
  1157.     \************************************************************************/
  1158.  
  1159.     // Must have same number of sub authorities
  1160.  
  1161.     bGotBadLookupThatIsNotLocalLogonSID = FALSE;  // Assume the best :)
  1162.  
  1163.     if ( ( *(GetSidSubAuthorityCount(psidLogonIdsSid))) !=
  1164.          ( *(GetSidSubAuthorityCount(psidSID        )))    )
  1165.     { // Not same number of sub-authorities, so can't be a match
  1166.       bGotBadLookupThatIsNotLocalLogonSID = TRUE;
  1167.     }
  1168.     else
  1169.     {
  1170.       // Force the last two sub-authorities to match
  1171.       *(GetSidSubAuthority( psidLogonIdsSid, 1 )) =
  1172.       *(GetSidSubAuthority( psidSID        , 1 ));
  1173.       *(GetSidSubAuthority( psidLogonIdsSid, 2 )) =
  1174.       *(GetSidSubAuthority( psidSID        , 2 ));
  1175.  
  1176.       /**********************************************************************\
  1177.       *
  1178.       * EqualPrefixSid could be used instead if we want to blast in all but
  1179.       *   the last sub-authority.  For demonstration purposes, as long as we
  1180.       *   did one of the two previous assignment statements, we may as well to
  1181.       *   the other and use EqualSID
  1182.       *
  1183.       \**********************************************************************/
  1184.  
  1185.       if (EqualSid(psidSID,psidLogonIdsSid))
  1186.       { printf("\n%sSID is the Local Logon SID   %s",ucIndentBuf,ucSIDStringBuf);
  1187.       }
  1188.       else
  1189.       { bGotBadLookupThatIsNotLocalLogonSID = TRUE;
  1190.       }
  1191.     }
  1192.     if (bGotBadLookupThatIsNotLocalLogonSID)
  1193.     {
  1194.       /**********************************************************************\
  1195.       *
  1196.       * ERROR_NONE_MAPPED means account unknown.  RegEdt32.exe will show
  1197.       *   1332-error-type accounts as Account Unknown, so we will also
  1198.       *
  1199.       \**********************************************************************/
  1200.  
  1201.       if (ERROR_NONE_MAPPED == dwLookupStatus)
  1202.       { printf("\n%sSID domain == %s, Name == %s    (Account Unknown)  %s",ucIndentBuf,ucDomainNmBuf,ucNameBuf,ucSIDStringBuf);
  1203.       }
  1204.       else
  1205.       { SetLastError(dwLookupStatus);
  1206.         PERR("LookupAccountSid");
  1207.         return(FALSE);
  1208.       }
  1209.     }
  1210.   }
  1211.   else
  1212.   { // Got good Lookup, so SID Is NOT the Local Logon SID
  1213.     printf("\n%sSID domain == %s, Name == %s   %s",ucIndentBuf,ucDomainNmBuf,ucNameBuf,ucSIDStringBuf);
  1214.  
  1215.     /************************************************************************\
  1216.     *
  1217.     * For demonstration purposes see which well-known SID it might be
  1218.     * For demonstration purposes do a silly search demonstrating
  1219.     *   no two well-known SIDs are equal
  1220.     *
  1221.     \************************************************************************/
  1222.  
  1223.     if (EqualSid(psidSID,psidNullSid))
  1224.     { printf("\n%sSID is the Null SID",ucIndentBuf);
  1225.     }
  1226.     if (EqualSid(psidSID,psidWorldSid))
  1227.     { printf("\n%sSID is the World SID",ucIndentBuf);
  1228.     }
  1229.     if (EqualSid(psidSID,psidLocalSid))
  1230.     { printf("\n%sSID is the Local SID",ucIndentBuf);
  1231.     }
  1232.     if (EqualSid(psidSID,psidCreatorOwnerSid))
  1233.     { printf("\n%sSID is the CreatorOwner SID",ucIndentBuf);
  1234.     }
  1235.     if (EqualSid(psidSID,psidCreatorGroupSid))
  1236.     { printf("\n%sSID is the CreatorGroup SID",ucIndentBuf);
  1237.     }
  1238.     if (EqualSid(psidSID,psidNtAuthoritySid))
  1239.     { printf("\n%sSID is the NtAuthority SID",ucIndentBuf);
  1240.     }
  1241.     if (EqualSid(psidSID,psidDialupSid))
  1242.     { printf("\n%sSID is the DialUp SID",ucIndentBuf);
  1243.     }
  1244.     if (EqualSid(psidSID,psidNetworkSid))
  1245.     { printf("\n%sSID is the Network SID",ucIndentBuf);
  1246.     }
  1247.     if (EqualSid(psidSID,psidBatchSid))
  1248.     { printf("\n%sSID is the Batch SID",ucIndentBuf);
  1249.     }
  1250.     if (EqualSid(psidSID,psidInteractiveSid))
  1251.     { printf("\n%sSID is the Interactive SID",ucIndentBuf);
  1252.     }
  1253.     if (EqualSid(psidSID,psidServiceSid))
  1254.     { printf("\n%sSID is the Service SID",ucIndentBuf);
  1255.     }
  1256.     if (EqualSid(psidSID,psidLocalSystemSid))
  1257.     { printf("\n%sSID is the LocalSystem SID",ucIndentBuf);
  1258.     }
  1259.     if (EqualSid(psidSID,psidBuiltinDomainSid))
  1260.     { printf("\n%sSID is the Builtin Domain SID",ucIndentBuf);
  1261.     }
  1262.   }
  1263.  
  1264.   switch (peAcctNameUse)
  1265.   { case                      SidTypeUser           :
  1266.       printf("\n%sSID type is SidTypeUser"          ,ucIndentBuf);
  1267.       break;
  1268.     case                      SidTypeGroup          :
  1269.       printf("\n%sSID type is SidTypeGroup"         ,ucIndentBuf);
  1270.       break;
  1271.     case                      SidTypeDomain         :
  1272.       printf("\n%sSID type is SidTypeDomain"        ,ucIndentBuf);
  1273.       break;
  1274.     case                      SidTypeAlias          :
  1275.       printf("\n%sSID type is SidTypeAlias"         ,ucIndentBuf);
  1276.       break;
  1277.     case                      SidTypeWellKnownGroup :
  1278.       printf("\n%sSID type is SidTypeWellKnownGroup",ucIndentBuf);
  1279.       break;
  1280.     case                      SidTypeDeletedAccount :
  1281.       printf("\n%sSID type is SidTypeDeletedAccount",ucIndentBuf);
  1282.       break;
  1283.     case                      SidTypeInvalid        :
  1284.       printf("\n%sSID type is SidTypeInvalid"       ,ucIndentBuf);
  1285.       break;
  1286.     case                      SidTypeUnknown        :
  1287.       printf("\n%sSID type is SidTypeUnknown"       ,ucIndentBuf);
  1288.       break;
  1289.     default                   :
  1290.       printf("\n%sSID type is IMPOSSIBLE!!!!  Run debugger, see value!",ucIndentBuf);
  1291.       break;
  1292.   }
  1293. }
  1294.  
  1295. /****************************************************************************\
  1296. *
  1297. * FUNCTION: SIDStringName
  1298. *
  1299. \****************************************************************************/
  1300.  
  1301. BOOL SIDStringName(PSID psidSID, LPTSTR lpszSIDStringName)
  1302. {
  1303.   /**************************************************************************\
  1304.   *
  1305.   * Unfortunately there is no api to return the SID Revision, and the number
  1306.   *   of bytes in the Identifier Authority must be expressed as a define
  1307.   *   (since the == operator won't operate on structures so mempcy has to be
  1308.   *   used for the identifier authority compares)
  1309.   *
  1310.   \**************************************************************************/
  1311.  
  1312.   DWORD dwNumSubAuthorities;
  1313.   DWORD dwLen;
  1314.   DWORD dwSubAuthorityI;
  1315.   #define BytesInIdentifierAuthority  6
  1316.   SID_IDENTIFIER_AUTHORITY siaSidAuthority;
  1317.   SID_IDENTIFIER_AUTHORITY siaNullSidAuthority    = SECURITY_NULL_SID_AUTHORITY;
  1318.   SID_IDENTIFIER_AUTHORITY siaWorldSidAuthority   = SECURITY_WORLD_SID_AUTHORITY;
  1319.   SID_IDENTIFIER_AUTHORITY siaLocalSidAuthority   = SECURITY_LOCAL_SID_AUTHORITY;
  1320.   SID_IDENTIFIER_AUTHORITY siaCreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
  1321.   SID_IDENTIFIER_AUTHORITY siaNtAuthority         = SECURITY_NT_AUTHORITY;
  1322.  
  1323.   dwLen = sprintf(lpszSIDStringName,"S-%d-",SID_REVISION);
  1324.  
  1325.   siaSidAuthority = *(GetSidIdentifierAuthority(psidSID));
  1326.  
  1327.   if      (0==memcmp(&siaSidAuthority,&siaNullSidAuthority   ,BytesInIdentifierAuthority))
  1328.   { dwLen += sprintf(lpszSIDStringName+dwLen,"0");
  1329.   }
  1330.   else if (0==memcmp(&siaSidAuthority,&siaWorldSidAuthority  ,BytesInIdentifierAuthority))
  1331.   { dwLen += sprintf(lpszSIDStringName+dwLen,"1");
  1332.   }
  1333.   else if (0==memcmp(&siaSidAuthority,&siaLocalSidAuthority  ,BytesInIdentifierAuthority))
  1334.   { dwLen += sprintf(lpszSIDStringName+dwLen,"2");
  1335.   }
  1336.   else if (0==memcmp(&siaSidAuthority,&siaCreatorSidAuthority,BytesInIdentifierAuthority))
  1337.   { dwLen += sprintf(lpszSIDStringName+dwLen,"3");
  1338.   }
  1339.   else if (0==memcmp(&siaSidAuthority,&siaNtAuthority        ,BytesInIdentifierAuthority))
  1340.   { dwLen += sprintf(lpszSIDStringName+dwLen,"5");
  1341.   }
  1342.   else
  1343.   { dwLen += sprintf(lpszSIDStringName+dwLen,"UnknownAuthority!");
  1344.   }
  1345.  
  1346.   dwNumSubAuthorities = (DWORD)( *(GetSidSubAuthorityCount(psidSID)) );
  1347.  
  1348.   for (dwSubAuthorityI=0; dwSubAuthorityI<dwNumSubAuthorities; dwSubAuthorityI++)
  1349.   { dwLen += sprintf(lpszSIDStringName+dwLen,"-%d",*(GetSidSubAuthority(psidSID,dwSubAuthorityI)));
  1350.   }
  1351.  
  1352.   return(TRUE);
  1353. }
  1354.  
  1355. /****************************************************************************\
  1356. *
  1357. * FUNCTION: ExamineAccessToken
  1358. *
  1359. \****************************************************************************/
  1360.  
  1361. VOID ExamineAccessToken(HANDLE hAccessToken)
  1362. { TOKEN_INFORMATION_CLASS ticInfoClass;
  1363.   #define                               SZ_TOK_INFO_BUF  2000
  1364.   UCHAR                   ucTokInfoBuf [SZ_TOK_INFO_BUF] = "";
  1365.   DWORD                   dwTokInfoBufSz;
  1366.   PTOKEN_USER             ptuTokenUser         = (PTOKEN_USER         )&ucTokInfoBuf;
  1367.   PTOKEN_OWNER            ptoTokenOwner        = (PTOKEN_OWNER        )&ucTokInfoBuf;
  1368.   PTOKEN_GROUPS           ptgTokenGroups       = (PTOKEN_GROUPS       )&ucTokInfoBuf;
  1369.   PTOKEN_PRIVILEGES       ptpTokenPrivileges   = (PTOKEN_PRIVILEGES   )&ucTokInfoBuf;
  1370.   PTOKEN_PRIMARY_GROUP    ptgTokenPrimaryGroup = (PTOKEN_PRIMARY_GROUP)&ucTokInfoBuf;
  1371.   PTOKEN_DEFAULT_DACL     ptdTokenDefaultDacl  = (PTOKEN_DEFAULT_DACL )&ucTokInfoBuf;
  1372.   PTOKEN_SOURCE           ptgTokenSource       = (PTOKEN_SOURCE       )&ucTokInfoBuf;
  1373.   PTOKEN_TYPE             ptgTokenType         = (PTOKEN_TYPE         )&ucTokInfoBuf;
  1374.   PSECURITY_IMPERSONATION_LEVEL psilSecurityImpersonationLevel = (PSECURITY_IMPERSONATION_LEVEL)&ucTokInfoBuf;
  1375.   DWORD                   dwGroupI;
  1376.   DWORD                   dwPrivilegeI;
  1377.   #define                               SZ_PRIV_INFO_BUF  250
  1378.   UCHAR                   ucPrivInfoBuf[SZ_PRIV_INFO_BUF] = "";
  1379.   DWORD                   dwPrivInfoBufSz;
  1380.   DWORD                   dwExtraBits;
  1381.   UCHAR                   ucIndentBitsBuf[SZ_INDENT_BUF]  = "";
  1382.  
  1383.   strcpy(ucIndentBitsBuf,"");
  1384.   strcat(ucIndentBitsBuf,"                                  ");
  1385.  
  1386.  
  1387.   if    (!I_DO_NOT_WANT_THIS_CODE_TO_CLUTTER_THIS_PROGRAM_S_OUTPUT)
  1388.   {
  1389.     ticInfoClass   = TokenUser;
  1390.     dwTokInfoBufSz = SZ_TOK_INFO_BUF;
  1391.  
  1392.     if (!GetTokenInformation(hAccessToken,
  1393.                              ticInfoClass,
  1394.                              ucTokInfoBuf,
  1395.                              (DWORD)SZ_TOK_INFO_BUF,
  1396.                              &dwTokInfoBufSz))
  1397.     { PERR("GetTokenInformation");
  1398.       return;
  1399.     }
  1400.  
  1401.     printf("\nToken's User SID");
  1402.     printf("\n    (this is a SID that is used to compare to SIDs in DACL(s) and SACL(s)");
  1403.  
  1404.     if(!LookupSIDName( (*ptuTokenUser).User.Sid,""))
  1405.     { PERR("LookupSIDName failed");
  1406.     }
  1407.  
  1408.     printf("\nToken's User SID Attributes == 0x%.8x",(*ptuTokenUser).User.Attributes);
  1409.     printf("\n    These should always be 0 - see \\mstools\\h\\winnt.h right after");
  1410.     printf("\n      the defines such as SE_GROUP_LOGON_ID - there are no user");
  1411.     printf("\n      attributes yet defined");
  1412.  
  1413.  
  1414.  
  1415.     ticInfoClass   = TokenGroups;
  1416.     dwTokInfoBufSz = SZ_TOK_INFO_BUF;
  1417.  
  1418.     if (!GetTokenInformation(hAccessToken,
  1419.                              ticInfoClass,
  1420.                              ucTokInfoBuf,
  1421.                              (DWORD)SZ_TOK_INFO_BUF,
  1422.                              &dwTokInfoBufSz))
  1423.     { PERR("GetTokenInformation");
  1424.       return;
  1425.     }
  1426.  
  1427.     printf("\nToken groups (%d)",(*ptgTokenGroups).GroupCount);
  1428.     printf("\n    (these SID(s) also are used to compare to SIDs in DACL(s) and SACL(s)");
  1429.  
  1430.     for (dwGroupI=0; dwGroupI<(*ptgTokenGroups).GroupCount; dwGroupI++)
  1431.     {
  1432.       DWORD dwAttributeBits = (*ptgTokenGroups).Groups[dwGroupI].Attributes;
  1433.       printf("\n  Token group (%d)",dwGroupI);
  1434.  
  1435.       if(!LookupSIDName( (*ptgTokenGroups).Groups[dwGroupI].Sid,"  "))
  1436.       { PERR("LookupSIDName failed");
  1437.       }
  1438.       printf("\n  Token's group (%d) attributes == 0x%.8x",dwGroupI,dwAttributeBits);
  1439.  
  1440.       if (dwAttributeBits)
  1441.       {
  1442.         if ((dwAttributeBits   & SE_GROUP_MANDATORY         ) == SE_GROUP_MANDATORY         )
  1443.         { printf("\n%s0x00000001 SE_GROUP_MANDATORY         ",ucIndentBitsBuf);
  1444.         }
  1445.         if ((dwAttributeBits   & SE_GROUP_ENABLED_BY_DEFAULT) == SE_GROUP_ENABLED_BY_DEFAULT)
  1446.         { printf("\n%s0x00000002 SE_GROUP_ENABLED_BY_DEFAULT",ucIndentBitsBuf);
  1447.         }
  1448.         if ((dwAttributeBits   & SE_GROUP_ENABLED           ) == SE_GROUP_ENABLED           )
  1449.         { printf("\n%s0x00000004 SE_GROUP_ENABLED           ",ucIndentBitsBuf);
  1450.         }
  1451.         if ((dwAttributeBits   & SE_GROUP_OWNER             ) == SE_GROUP_OWNER             )
  1452.         { printf("\n%s0x00000008 SE_GROUP_OWNER             ",ucIndentBitsBuf);
  1453.         }
  1454.         if ((dwAttributeBits   & SE_GROUP_LOGON_ID          ) == SE_GROUP_LOGON_ID          )
  1455.         { printf("\n%s0xC0000000 SE_GROUP_LOGON_ID          ",ucIndentBitsBuf);
  1456.         }
  1457.  
  1458.         dwExtraBits = dwAttributeBits & ( ~( SE_GROUP_MANDATORY
  1459.                                            | SE_GROUP_ENABLED_BY_DEFAULT
  1460.                                            | SE_GROUP_ENABLED
  1461.                                            | SE_GROUP_OWNER
  1462.                                            | SE_GROUP_LOGON_ID) );
  1463.         if (0 != dwExtraBits)
  1464.         { printf("\n          Extra attribute bits == 0x%.8x <-This is a problem, should be all 0s",dwExtraBits);
  1465.         }
  1466.       }
  1467.     }
  1468.  
  1469.  
  1470.  
  1471.     ticInfoClass   = TokenPrivileges;
  1472.     dwTokInfoBufSz = SZ_TOK_INFO_BUF;
  1473.  
  1474.     if (!GetTokenInformation(hAccessToken,
  1475.                              ticInfoClass,
  1476.                              ucTokInfoBuf,
  1477.                              (DWORD)SZ_TOK_INFO_BUF,
  1478.                              &dwTokInfoBufSz))
  1479.     { PERR("GetTokenInformation");
  1480.       return;
  1481.     }
  1482.  
  1483.     printf("\nToken privileges (%d)",(*ptpTokenPrivileges).PrivilegeCount);
  1484.     printf("\n  NOTE: Most token privileges are not enabled by default.");
  1485.     printf("\n    For example the privilege to reboot or logoff is not.");
  1486.     printf("\n    0x00000000 for attributes implies the privilege is not enabled.");
  1487.     printf("\n    Use care when enabling privileges.  Enable only those needed,");
  1488.     printf("\n      and leave them enabled only for as long as they are needed.");
  1489.  
  1490.     for (dwPrivilegeI=0; dwPrivilegeI<(*ptpTokenPrivileges).PrivilegeCount; dwPrivilegeI++)
  1491.     {
  1492.       LUID  luidTokenLuid   = (*ptpTokenPrivileges).Privileges[dwPrivilegeI].Luid;
  1493.       DWORD dwAttributeBits = (*ptpTokenPrivileges).Privileges[dwPrivilegeI].Attributes;
  1494.  
  1495.       dwPrivInfoBufSz = SZ_PRIV_INFO_BUF;
  1496.  
  1497.       if (!LookupPrivilegeName(NULL,
  1498.                                (PLUID)&luidTokenLuid,
  1499.                                (LPTSTR)ucPrivInfoBuf,
  1500.                                (LPDWORD)&dwPrivInfoBufSz))
  1501.       { PERR("LookUpPrivilegeName");
  1502.         return;
  1503.       }
  1504.  
  1505.       printf("\n  Token's privilege (%.2d) name       == %s",dwPrivilegeI,ucPrivInfoBuf);
  1506.  
  1507.       printf("\n  Token's privilege (%.2d) attributes == 0x%.8x",dwPrivilegeI,dwAttributeBits);
  1508.  
  1509.       if (dwAttributeBits)
  1510.       {
  1511.         if ((dwAttributeBits   & SE_PRIVILEGE_ENABLED_BY_DEFAULT) == SE_PRIVILEGE_ENABLED_BY_DEFAULT)
  1512.         { printf("\n%s     0x00000001 SE_PRIVILEGE_ENABLED_BY_DEFAULT",ucIndentBitsBuf);
  1513.         }
  1514.         if ((dwAttributeBits   & SE_PRIVILEGE_ENABLED           ) == SE_PRIVILEGE_ENABLED           )
  1515.         { printf("\n%s     0x00000002 SE_PRIVILEGE_ENABLED           ",ucIndentBitsBuf);
  1516.         }
  1517.         if ((dwAttributeBits   & SE_PRIVILEGE_USED_FOR_ACCESS   ) == SE_PRIVILEGE_USED_FOR_ACCESS   )
  1518.         { printf("\n%s     0x80000000 SE_PRIVILEGE_USED_FOR_ACCESS   ",ucIndentBitsBuf);
  1519.         }
  1520.  
  1521.         dwExtraBits = dwAttributeBits & ( ~( SE_PRIVILEGE_ENABLED_BY_DEFAULT
  1522.                                            | SE_PRIVILEGE_ENABLED
  1523.                                            | SE_PRIVILEGE_USED_FOR_ACCESS ) );
  1524.         if (0 != dwExtraBits)
  1525.         { printf("\n               Extra attribute bits == 0x%.8x <-This is a problem, should be all 0s",dwExtraBits);
  1526.         }
  1527.       }
  1528.     }
  1529.  
  1530.  
  1531.  
  1532.     ticInfoClass   = TokenOwner;
  1533.     dwTokInfoBufSz = SZ_TOK_INFO_BUF;
  1534.  
  1535.     if (!GetTokenInformation(hAccessToken,
  1536.                              ticInfoClass,
  1537.                              ucTokInfoBuf,
  1538.                              (DWORD)SZ_TOK_INFO_BUF,
  1539.                              &dwTokInfoBufSz))
  1540.     { PERR("GetTokenInformation");
  1541.       return;
  1542.     }
  1543.  
  1544.     printf("\nToken's Owner SID");
  1545.     printf("\n    (this is NOT a SID that is used to compare to SIDs in DACL(s) and SACL(s)");
  1546.  
  1547.     if(!LookupSIDName((*ptoTokenOwner).Owner,""))
  1548.     { PERR("LookupSIDName failed");
  1549.     }
  1550.  
  1551.  
  1552.  
  1553.     ticInfoClass   = TokenPrimaryGroup;
  1554.     dwTokInfoBufSz = SZ_TOK_INFO_BUF;
  1555.  
  1556.     if (!GetTokenInformation(hAccessToken,
  1557.                              ticInfoClass,
  1558.                              ucTokInfoBuf,
  1559.                              (DWORD)SZ_TOK_INFO_BUF,
  1560.                              &dwTokInfoBufSz))
  1561.     { PERR("GetTokenInformation");
  1562.       return;
  1563.     }
  1564.  
  1565.     printf("\nToken's Primary Group SID");
  1566.     printf("\n    (Current uses are Posix and Macintosh client support)");
  1567.  
  1568.     if(!LookupSIDName((*ptgTokenPrimaryGroup).PrimaryGroup,""))
  1569.     { PERR("LookupSIDName failed");
  1570.     }
  1571.  
  1572.  
  1573.  
  1574.     ticInfoClass   = TokenDefaultDacl;
  1575.     dwTokInfoBufSz = SZ_TOK_INFO_BUF;
  1576.  
  1577.     if (!GetTokenInformation(hAccessToken,
  1578.                              ticInfoClass,
  1579.                              ucTokInfoBuf,
  1580.                              (DWORD)SZ_TOK_INFO_BUF,
  1581.                              &dwTokInfoBufSz))
  1582.     { PERR("GetTokenInformation");
  1583.       return;
  1584.     }
  1585.  
  1586.     if (NULL         == (*ptdTokenDefaultDacl).DefaultDacl)
  1587.     { printf("\nToken has a NULL Default DACL explicitly specified (allows all access to");
  1588.       printf("\n    Everyone, only on objects that are created where the object's Dacl is");
  1589.       printf("\n    assigned by default from this default Dacl in this access token)");
  1590.     }
  1591.     else if(!ExamineACL((*ptdTokenDefaultDacl).DefaultDacl,"  ",DefaultDaclInAccesTokenAccessMask))
  1592.     {  PERR("ExamineACL failed");
  1593.     }
  1594.  
  1595.  
  1596.  
  1597.     ticInfoClass   = TokenSource;
  1598.     dwTokInfoBufSz = SZ_TOK_INFO_BUF;
  1599.  
  1600.     if (!GetTokenInformation(hAccessToken,
  1601.                              ticInfoClass,
  1602.                              ucTokInfoBuf,
  1603.                              (DWORD)SZ_TOK_INFO_BUF,
  1604.                              &dwTokInfoBufSz))
  1605.     { PERR("GetTokenInformation");
  1606.       return;
  1607.     }
  1608.  
  1609.     printf("\nToken's Source");
  1610.     printf("\n  Source Name       == %s",(*ptgTokenSource).SourceName);
  1611.     printf("\n  Source Identifier == 0x%.8x",(*ptgTokenSource).SourceIdentifier);
  1612.  
  1613.  
  1614.  
  1615.     ticInfoClass   = TokenType;
  1616.     dwTokInfoBufSz = SZ_TOK_INFO_BUF;
  1617.  
  1618.     if (!GetTokenInformation(hAccessToken,
  1619.                              ticInfoClass,
  1620.                              ucTokInfoBuf,
  1621.                              (DWORD)SZ_TOK_INFO_BUF,
  1622.                              &dwTokInfoBufSz))
  1623.     { PERR("GetTokenInformation");
  1624.       return;
  1625.     }
  1626.  
  1627.     switch (*ptgTokenType)
  1628.     { case  TokenPrimary       :
  1629.         printf("\nToken's Type is TokenPrimary");
  1630.         break;
  1631.       case  TokenImpersonation :
  1632.         printf("\nToken's Type is TokenImpersonation");
  1633.         printf("\n    Hence the token's TokenImpersonationLevel can be examined");
  1634.  
  1635.         ticInfoClass   = TokenImpersonationLevel;
  1636.         dwTokInfoBufSz = SZ_TOK_INFO_BUF;
  1637.  
  1638.         if (!GetTokenInformation(hAccessToken,
  1639.                                  ticInfoClass,
  1640.                                  ucTokInfoBuf,
  1641.                                  (DWORD)SZ_TOK_INFO_BUF,
  1642.                                  &dwTokInfoBufSz))
  1643.         { PERR("GetTokenInformation");
  1644.           return;
  1645.         }
  1646.  
  1647.         switch (*psilSecurityImpersonationLevel)
  1648.         { case                     SecurityAnonymous      :
  1649.             printf("\n  Token is a SecurityAnonymous impersonation token");
  1650.             break;
  1651.           case                     SecurityIdentification :
  1652.             printf("\n  Token is a SecurityIdentification impersonation token");
  1653.             break;
  1654.           case                     SecurityImpersonation  :
  1655.             printf("\n  Token is a SecurityImpersonation impersonation token");
  1656.             break;
  1657.           case                     SecurityDelegation     :
  1658.             printf("\n  Token is a SecurityDelegation impersonation token");
  1659.             break;
  1660.           default                   :
  1661.             printf("\n  Token is an ILLEGAL KIND OF impersonation token!!! == 0x%.8x",*psilSecurityImpersonationLevel);
  1662.             break;
  1663.         }
  1664.  
  1665.       default                  :
  1666.         printf("\nToken's Type is ILLEGAL!!! == 0x%.8x",*ptgTokenType);
  1667.         break;
  1668.     }
  1669.  
  1670.  
  1671.  
  1672.     printf("\n\n");
  1673.  
  1674.   }
  1675. }
  1676.  
  1677. /****************************************************************************\
  1678. *
  1679. * FUNCTION: SetPrivilegeInAccessToken
  1680. *
  1681. \****************************************************************************/
  1682.  
  1683. BOOL SetPrivilegeInAccessToken(VOID)
  1684. {
  1685.   HANDLE           hProcess;
  1686.   HANDLE           hAccessToken;
  1687.   LUID             luidPrivilegeLUID;
  1688.   TOKEN_PRIVILEGES tpTokenPrivilege;
  1689.  
  1690.   hProcess = GetCurrentProcess();
  1691.   if (!hProcess)
  1692.   { PERR("GetCurrentProcess");
  1693.     return(FALSE);
  1694.   }
  1695.  
  1696.   if (!OpenProcessToken(hProcess,
  1697.                         TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,
  1698.                         &hAccessToken))
  1699.   { PERR("OpenProcessToken");
  1700.     return(FALSE);
  1701.   }
  1702.  
  1703.   /**************************************************************************\
  1704.   *
  1705.   * Get LUID of SeSecurityPrivilege privilege
  1706.   *
  1707.   \**************************************************************************/
  1708.  
  1709.   if (!LookupPrivilegeValue(NULL,
  1710.                             "SeSecurityPrivilege",
  1711.                             &luidPrivilegeLUID))
  1712.   { PERR("LookupPrivilegeValue");
  1713.     printf("\nThe above error means you need to log on as an Administrator");
  1714.     return(FALSE);
  1715.   }
  1716.  
  1717.   /**************************************************************************\
  1718.   *
  1719.   * Enable the SeSecurityPrivilege privilege using the LUID just
  1720.   *   obtained
  1721.   *
  1722.   \**************************************************************************/
  1723.  
  1724.   tpTokenPrivilege.PrivilegeCount = 1;
  1725.   tpTokenPrivilege.Privileges[0].Luid = luidPrivilegeLUID;
  1726.   tpTokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  1727.  
  1728.   AdjustTokenPrivileges (hAccessToken,
  1729.                          FALSE,  // Do not disable all
  1730.                          &tpTokenPrivilege,
  1731.                          sizeof(TOKEN_PRIVILEGES),
  1732.                          NULL,   // Ignore previous info
  1733.                          NULL);  // Ignore previous info
  1734.  
  1735.   if ( GetLastError() != NO_ERROR )
  1736.   { PERR("AdjustTokenPrivileges");
  1737.     return(FALSE);
  1738.   }
  1739.  
  1740.   return(TRUE);
  1741. }
  1742.  
  1743. /****************************************************************************\
  1744. *
  1745. * FUNCTION: InitializeWellKnownSIDs
  1746. *
  1747. \****************************************************************************/
  1748.  
  1749. VOID InitializeWellKnownSIDs(VOID)
  1750. {
  1751.   DWORD dwSidWith0SubAuthorities;
  1752.   DWORD dwSidWith1SubAuthority;
  1753.   DWORD dwSidWith2SubAuthorities;
  1754.   DWORD dwSidWith3SubAuthorities;
  1755.   DWORD dwSidWith4SubAuthorities;
  1756.  
  1757.   SID_IDENTIFIER_AUTHORITY siaNullSidAuthority    = SECURITY_NULL_SID_AUTHORITY;
  1758.   SID_IDENTIFIER_AUTHORITY siaWorldSidAuthority   = SECURITY_WORLD_SID_AUTHORITY;
  1759.   SID_IDENTIFIER_AUTHORITY siaLocalSidAuthority   = SECURITY_LOCAL_SID_AUTHORITY;
  1760.   SID_IDENTIFIER_AUTHORITY siaCreatorSidAuthority = SECURITY_CREATOR_SID_AUTHORITY;
  1761.   SID_IDENTIFIER_AUTHORITY siaNtAuthority         = SECURITY_NT_AUTHORITY;
  1762.  
  1763.   //  These SID sizes need to be allocated
  1764.  
  1765.   dwSidWith0SubAuthorities = GetSidLengthRequired( 0 );
  1766.   dwSidWith1SubAuthority   = GetSidLengthRequired( 1 );
  1767.   dwSidWith2SubAuthorities = GetSidLengthRequired( 2 );
  1768.   dwSidWith3SubAuthorities = GetSidLengthRequired( 3 );
  1769.   dwSidWith4SubAuthorities = GetSidLengthRequired( 4 );
  1770.  
  1771.   //  Allocate and initialize the universal SIDs
  1772.  
  1773.   psidNullSid         = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1774.   psidWorldSid        = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1775.   psidLocalSid        = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1776.   psidCreatorOwnerSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1777.   psidCreatorGroupSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1778.  
  1779.   InitializeSid( psidNullSid,         &siaNullSidAuthority,    1 );
  1780.   InitializeSid( psidWorldSid,        &siaWorldSidAuthority,   1 );
  1781.   InitializeSid( psidLocalSid,        &siaLocalSidAuthority,   1 );
  1782.   InitializeSid( psidCreatorOwnerSid, &siaCreatorSidAuthority, 1 );
  1783.   InitializeSid( psidCreatorGroupSid, &siaCreatorSidAuthority, 1 );
  1784.  
  1785.   *(GetSidSubAuthority( psidNullSid,         0 )) = SECURITY_NULL_RID;
  1786.   *(GetSidSubAuthority( psidWorldSid,        0 )) = SECURITY_WORLD_RID;
  1787.   *(GetSidSubAuthority( psidLocalSid,        0 )) = SECURITY_LOCAL_RID;
  1788.   *(GetSidSubAuthority( psidCreatorOwnerSid, 0 )) = SECURITY_CREATOR_OWNER_RID;
  1789.   *(GetSidSubAuthority( psidCreatorGroupSid, 0 )) = SECURITY_CREATOR_GROUP_RID;
  1790.  
  1791.   // Allocate and initialize the NT defined SIDs
  1792.  
  1793.   psidNtAuthoritySid   = (PSID)LocalAlloc(LPTR,dwSidWith0SubAuthorities);
  1794.   psidDialupSid        = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1795.   psidNetworkSid       = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1796.   psidBatchSid         = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1797.   psidInteractiveSid   = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1798.   psidLogonIdsSid      = (PSID)LocalAlloc(LPTR,dwSidWith3SubAuthorities);
  1799.   psidServiceSid       = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1800.   psidLocalSystemSid   = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1801.   psidBuiltinDomainSid = (PSID)LocalAlloc(LPTR,dwSidWith1SubAuthority);
  1802.  
  1803.   InitializeSid( psidNtAuthoritySid,   &siaNtAuthority, 0 );
  1804.   InitializeSid( psidDialupSid,        &siaNtAuthority, 1 );
  1805.   InitializeSid( psidNetworkSid,       &siaNtAuthority, 1 );
  1806.   InitializeSid( psidBatchSid,         &siaNtAuthority, 1 );
  1807.   InitializeSid( psidInteractiveSid,   &siaNtAuthority, 1 );
  1808.   InitializeSid( psidLogonIdsSid,      &siaNtAuthority, 3 );
  1809.   InitializeSid( psidServiceSid,       &siaNtAuthority, 1 );
  1810.   InitializeSid( psidLocalSystemSid,   &siaNtAuthority, 1 );
  1811.   InitializeSid( psidBuiltinDomainSid, &siaNtAuthority, 1 );
  1812.  
  1813.   *(GetSidSubAuthority( psidDialupSid,        0 )) = SECURITY_DIALUP_RID;
  1814.   *(GetSidSubAuthority( psidNetworkSid,       0 )) = SECURITY_NETWORK_RID;
  1815.   *(GetSidSubAuthority( psidBatchSid,         0 )) = SECURITY_BATCH_RID;
  1816.   *(GetSidSubAuthority( psidInteractiveSid,   0 )) = SECURITY_INTERACTIVE_RID;
  1817.   *(GetSidSubAuthority( psidLogonIdsSid,      0 )) = SECURITY_LOGON_IDS_RID;
  1818.   *(GetSidSubAuthority( psidLogonIdsSid,      1 )) = 0; // Bogus!
  1819.   *(GetSidSubAuthority( psidLogonIdsSid,      2 )) = 0; // Also bogus!
  1820.   *(GetSidSubAuthority( psidServiceSid,       0 )) = SECURITY_SERVICE_RID;
  1821.   *(GetSidSubAuthority( psidLocalSystemSid,   0 )) = SECURITY_LOCAL_SYSTEM_RID;
  1822.   *(GetSidSubAuthority( psidBuiltinDomainSid, 0 )) = SECURITY_BUILTIN_DOMAIN_RID;
  1823. }
  1824.  
  1825. /****************************************************************************\
  1826. *
  1827. * FUNCTION: DisplayHelp
  1828. *
  1829. \****************************************************************************/
  1830.  
  1831. VOID DisplayHelp(VOID)
  1832. {
  1833.   printf("\nTo run type CHECK_SD and 0 or 1 parameters.  Syntax:");
  1834.   printf("\n  CHECK_SD");
  1835.   printf("\n      or");
  1836.   printf("\n  CHECK_SD filename");
  1837.   printf("\n           filename is the name of the file that is passed");
  1838.   printf("\n             to GetFileSecurity() to fetch the SD to examine");
  1839.   printf("\nExamples:");
  1840.   printf("\n  CHECK_SD            Checks the SD on A: (this is the default)");
  1841.   printf("\n  CHECK_SD \\\\.\\A:     Checks the SD on A:");
  1842.   printf("\n  CHECK_SD d:\\a.fil   Checks the SD on d:\a.fil");
  1843.   printf("\n  CHECK_SD A:         Checks the SD on the A: root, but that");
  1844.   printf("\n                        is not where the DACL is that controls");
  1845.   printf("\n                        access to the floppy, so don't do this");
  1846. }
  1847.